/*
 * @Author: lee_124
 * @Date: 2022-01-25 16:07:50
 * @LastEditTime: 2022-01-26 11:44:38
 * @LastEditors: lee_124
 * @Description:
 * @FilePath: /public_demo/src/utils/util.js
 */

//  简易版
/**
 * 节流函数 一个函数执行一次后，只有大于设定的执行周期才会执行第二次。有个需要频繁触发的函数，出于优化性能的角度，在规定时间内，只让函数触发的第一次生效，后面的不生效。
 * 使用场景：滚动加载更多、搜索框搜的索联想功能、高频点击、表单重复提交……
 * @param fn要被节流的函数
 * @param delay规定的时间
 */
// function _throttle(fn, delay = 200) {
//   console.log("vvv");
//   //记录上一次函数触发的时间
//   var lastTime = 0;
//   return function () {
//     //记录当前函数触发的时间
//     var nowTime = Date.now();

//     if (nowTime - lastTime > delay) {
//       console.log(". . . ", nowTime - lastTime > delay);

//       //修正this指向问题
//       fn.call(this);
//       //同步执行结束时间
//       lastTime = nowTime;
//     }
//   };
// }

// 简易版
/**
 * 防抖函数  一个需要频繁触发的函数，在规定时间内，只让最后一次生效，前面的不生效
 * 使用场景：搜索框搜索输入，并在输入完以后自动搜索、手机号，邮箱验证输入检测、窗口大小 resize 变化后，再重新渲染
 * @param fn要被节流的函数
 * @param delay规定的时间
 */
// function _debounce(fn, delay = 200) {
//   //记录上一次的延时器
//   var timer = null;
//   return function () {
//     //清除上一次的演示器
//     if (timer) clearTimeout(timer);
//     //重新设置新的延时器
//     timer = setTimeout(function () {
//       //修正this指向问题
//       fn.apply(this);
//     }, delay);
//   };
// }

// 节流加强版
/**
 *
 * @param {*} fn 节流后执行的回调函数
 * @param {*} delay 节流规定的时间
 * @param {*} immediate 是否第一次立即执行
 */
function _throttle(fn, delay = 200, immediate = false) {
  let flag = true;
  return function () {
    if (flag) {
      flag = false;
      immediate && fn.call(this);
      setTimeout(() => {
        !immediate && fn.call(this);
        flag = true;
      }, delay);
    }
  };
}

// 防抖加强版
/**
 *
 * @param {*} fn 防抖后执行的回调函数
 * @param {*} delay  防抖规定的时间
 * @param {*} immediate  是否第一次立即执行
 */
function _debounce(fn, delay = 200, immediate = false) {
  let timer,
    flag = true;
  return function () {
    // 需要立即执行的情况
    if (immediate) {
      if (flag) {
        fn.call(this);
        flag = false;
      } else {
        clearTimeout(timer);
        timer = setTimeout(() => {
          fn.call(this);
          flag = true;
        }, delay);
      }
    } else {
      // 非立即执行的情况
      clearTimeout(timer);
      timer = setTimeout(() => {
        fn.call(this);
      }, delay);
    }
  };
}

export { _throttle, _debounce };
